package com.tianye.salon.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HlFileUtils {
	
	private static final Logger log = LoggerFactory.getLogger(HlFileUtils.class);
	
	/**
	 * 
	 * @Title: transcodingFileName
	 * @Description: 对文件名进行转码以防止中文乱码
	 * @param @param
	 *            fileName
	 * @param @return
	 * @param @throws
	 *            UnsupportedEncodingException
	 * @return String
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月6日 下午4:05:27
	 */
	public static String transcodingFileName(String fileName) throws UnsupportedEncodingException {
		if (fileName == null || fileName.equals("")) {
			return fileName;
		}
		return new String(fileName.getBytes("UTF-8"), "iso-8859-1");
	}

	/**
	 * 
	 * @Title: checkFolderExists
	 * @Description: 检查文件目录是否存在
	 * @param @param
	 *            folderPath
	 * @param @return
	 * @return boolean
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月4日 下午4:47:07
	 */
	public static boolean checkFolderExists(String folderPath) {
		// 文件目录不能为空
		if (folderPath == null || folderPath.equals("")) {
			return false;
		}
		// 补全目录路径分隔符
		if (!folderPath.endsWith(File.separator)) {
			folderPath = folderPath + File.separator;
		}
		File file = new File(folderPath);
		if (!file.isDirectory()) {
			return false;
		}
		return file.exists();
	}

	/**
	 * 
	 * @Title: createFolder
	 * @Description: 创建文件目录，如果存在返回false
	 * @param @param
	 *            folderPath
	 * @param @return
	 * @return boolean
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月4日 下午4:18:10
	 */
	public static boolean createFolder(String folderPath) {
		// 文件目录不能为空
		if (folderPath == null || folderPath.equals("")) {
			return false;
		}
		// 补全文件分隔符
		if (!folderPath.endsWith(File.separator)) {
			folderPath = folderPath + File.separator;
		}
		File file = new File(folderPath);
		if (file.exists()) {
			return false;
		}
		return file.mkdir();
	}

	/**
	 * 
	 * @Title: createFolders
	 * @Description: 创建文件目录，如果父目录不存在一并创建
	 * @param @param
	 *            folderPath
	 * @param @return
	 * @return boolean
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月4日 下午4:28:14
	 */
	public static boolean createFolders(String folderPath) {
		// 文件目录不能为空
		if (folderPath == null || folderPath.equals("")) {
			return false;
		}
		// 补全文件分隔符
		if (!folderPath.endsWith(File.separator)) {
			folderPath = folderPath + File.separator;
		}
		File file = new File(folderPath);
		if (file.exists()) {
			return false;
		}
		return file.mkdirs();
	}

	/**
	 * 
	 * @Title: deleteFolder
	 * @Description: 删除文件夹
	 * @param @param
	 *            folderPath 文件夹全路径
	 * @param @return
	 * @return boolean
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月4日 下午3:49:06
	 */
	public static boolean deleteFolder(String folderPath) {
		// 路径不能为空
		if (folderPath == null || folderPath.equals("")) {
			return false;
		}
		// 文件夹名称不能为空
		if (folderPath == null || folderPath.equals("")) {
			return false;
		}
		// 如果路径不以文件分隔符结尾，自动补全
		if (!folderPath.endsWith(File.separator)) {
			folderPath = folderPath + File.separator;
		}
		File folderFile = new File(folderPath);
		// 如果目录不存在或不是一个目录，则返回false
		if (!folderFile.exists() || !folderFile.isDirectory()) {
			return false;
		}

		boolean flag = true;
		// 循环删除该目录下的子目录和文件
		File[] files = folderFile.listFiles();
		if (files != null && files.length > 0) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].isFile()) {
					flag = deleteFile(files[i].getAbsolutePath());
					if (!flag)
						break;
				} else {
					// 递归删除
					flag = deleteFolder(files[i].getAbsolutePath());
					if (!flag)
						break;
				}
			}
		}
		if (!flag) {
			return false;
		}
		if (folderFile.delete()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 
	 * @Title: deleteFile
	 * @Description: 删除文件
	 * @param @param
	 *            path 文件路径
	 * @param @param
	 *            fileName 文件名
	 * @param @return
	 * @return boolean
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月4日 下午3:48:40
	 */
	public static boolean deleteFile(String path, String fileName) {
		// 路径不能为空
		if (path == null || path.equals("")) {
			return false;
		}
		// 文件名称不能为空
		if (fileName == null || fileName.equals("")) {
			return false;
		}
		// 如果路径不以文件分隔符结尾，自动补全
		if (!path.endsWith(File.separator)) {
			path = path + File.separator;
		}

		return deleteFile(path + fileName);
	}

	/**
	 * 
	 * @Title: deleteFile
	 * @Description: 删除文件
	 * @param @param
	 *            absolutePath 文件的全路径名
	 * @param @return
	 * @return boolean
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月4日 下午3:48:09
	 */
	public static boolean deleteFile(String absolutePath) {
		File file = new File(absolutePath);
		// 如果文件不存在或不是一个文件返回false
		if (!file.exists() || !file.isFile()) {
			return false;
		}
		return file.delete();
	}

	/**
	 * 
	 * @Title: checkFileExists
	 * @Description: 检查文件是否存在
	 * @param @param
	 *            absolutePath
	 * @param @return
	 * @return boolean
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月4日 下午4:38:14
	 */
	public static boolean checkFileExists(String absolutePath) {
		File file = new File(absolutePath);
		if (!file.isFile()) {
			return false;
		}
		return file.exists();
	}

	/**
	 * 
	 * @Title: toByteArray
	 * @Description: 传统读取文件流到字节数组
	 * @param @param
	 *            filePathName 文件全路径名
	 * @param @return
	 * @param @throws
	 *            IOException
	 * @return byte[]
	 * @throws @author
	 *             fengchao
	 * @date 2017年8月6日 下午12:09:44
	 */
	public static byte[] toByteArray(String filePathName) throws IOException {
		File file = new File(filePathName);
		if (!file.isFile() || !file.exists()) {
			throw new FileNotFoundException(filePathName);
		}
		ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
		BufferedInputStream bufferedInputStream = null;
		try {
			bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
			int buffer_size = 1024;
			byte[] buffer = new byte[buffer_size];
			int len = 0;
			while (-1 != (len = bufferedInputStream.read(buffer, 0, buffer_size))) {
				bos.write(buffer, 0, len);
			}
			return bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (bufferedInputStream != null) {
				bufferedInputStream.close();
			}
			bos.close();
		}
	}

	/**
	 * 
	 * @Title: toByteArrayNio 
	 * @Description: NIO读取
	 * @param @param filePathName
	 * @param @return
	 * @param @throws IOException 
	 * @return byte[] 
	 * @throws 
	 * @author fengchao
	 * @date 2017年8月6日 下午5:21:02
	 */
	public static byte[] toByteArrayNio(String filePathName) throws IOException {
		File file = new File(filePathName);
		if (!file.isFile() || !file.exists()) {
			throw new FileNotFoundException(filePathName);
		}
		FileChannel fileChannel = null;
		FileInputStream fs = null;
		try {
			fs = new FileInputStream(file);
			fileChannel = fs.getChannel();
			ByteBuffer byteBuffer = ByteBuffer.allocate((int) fileChannel.size());
			while (fileChannel.read(byteBuffer) > 0) {
			}
			return byteBuffer.array();

		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				fileChannel.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			try {
				fs.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

	/**
	 * 
	 * @Title: toByteArrayFast 
	 * @Description: 大文件读取
	 * @param @param filePathName
	 * @param @return
	 * @param @throws IOException 
	 * @return byte[] 
	 * @throws 
	 * @author fengchao
	 * @date 2017年8月6日 下午5:20:06
	 */
	@SuppressWarnings("resource")
	public static byte[] toByteArrayFast(String filePathName) throws IOException {
		File file = new File(filePathName);
		if (!file.isFile() || !file.exists()) {
			throw new FileNotFoundException(filePathName);
		}
		FileChannel fileChannel = null;
		try {
			fileChannel = new RandomAccessFile(filePathName, "r").getChannel();
			MappedByteBuffer byteBuffer = fileChannel.map(MapMode.READ_ONLY, 0, fileChannel.size()).load();
			byte[] result = new byte[(int) fileChannel.size()];
			if (byteBuffer.remaining() > 0) {
				byteBuffer.get(result, 0, byteBuffer.remaining());
			}
			return result;
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				fileChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 
	* @Title: moveFile 
	* @Description: 移动文件夹或文件
	* @param @param oldPath 原文件夹或文件父路径
	* @param @param newPath 新文件夹或文件父路径
	* @param @param fileName 文件夹或文件名称，如果是文件的话需要带扩展名
	* @param @return    设定文件 
	* @return boolean    返回类型 
	* @throws 
	* @author fengchao
	* @date 2017年8月15日 下午2:35:21
	 */
	public static boolean moveFile(String oldPath, String newPath, String fileName) {
		// 原文件路径不能为空
		if (oldPath == null || oldPath.equals("")) {
			return false;
		}
		// 新文件路径不能为空
		if (newPath == null || newPath.equals("")) {
			return false;
		}
		// 文件名不能为空
		if (fileName == null || fileName.equals("")) {
			return false;
		}
		// 路径相同
		if (oldPath.equals(newPath)) {
			return false;
		}
		if (!oldPath.endsWith(File.separator)) {
			oldPath = oldPath + File.separator;
		}
		File oldFile = new File(oldPath + fileName);
		if (!oldFile.exists())
			return false;
		File newPathFile = new File(newPath);
		if (!newPathFile.exists()) {
			//如果目标文件目录不存在则创建
			newPathFile.mkdirs();
		}
		if (!newPath.endsWith(File.separator)) {
			newPath = newPath + File.separator;
		}
		File newFile = new File(newPath + fileName);
		return oldFile.renameTo(newFile);
	}
	
	/**
	 * 
	* @Title: copyFile 
	* @Description: 拷贝文件或目录
	* @param @param srcPath 源文件或目录父路径
	* @param @param destPath 目标文件或目录父路径
	* @param @param fileName 文件或目录名称，如果是文件的话需要带扩展名
	* @param @return
	* @param @throws IOException    设定文件 
	* @return boolean    返回类型 
	* @throws 
	* @author fengchao
	* @date 2017年8月15日 下午4:49:52
	 */
	public static boolean copyFile(String srcPath, String destPath, String fileName) throws IOException {
		// 原文件路径不能为空
		if (srcPath == null || srcPath.equals("")) {
			return false;
		}
		// 新文件路径不能为空
		if (destPath == null || destPath.equals("")) {
			return false;
		}
		// 文件名不能为空
		if (fileName == null || fileName.equals("")) {
			return false;
		}
		// 路径相同
		if (srcPath.equals(destPath)) {
			return true;
		}
		// 使用Apache common io 进行文件拷贝
		if (!srcPath.endsWith(File.separator)) {
			srcPath = srcPath + File.separator;
		}
		File srcFile = new File(srcPath + fileName);
		if (!destPath.endsWith(File.separator)) {
			destPath = destPath + File.separator;
		}
		File destFile = new File(destPath + fileName);
		if (srcFile.isDirectory()) {
			// 拷贝目录
			FileUtils.copyDirectory(srcFile, destFile);
		} else {
			// 拷贝文件
			FileUtils.copyFile(srcFile, destFile);
		}
		return true;
	}
	
	/**
	 * 
	* @Title: renameFile 
	* @Description: 文件或目录更名 
	* @param @param filePath 文件路径
	* @param @param oldFileName 旧文件名
	* @param @param newFileName 新文件名
	* @param @return    设定文件 
	* @return boolean    返回类型 
	* @throws 
	* @author fengchao
	* @date 2017年8月15日 下午5:16:37
	 */
	public static boolean renameFile(String filePath, String oldFileName, String newFileName) {
		// 文件路径不能为空
		if (filePath == null || filePath.equals("")) {
			return false;
		}
		// 源文件名不能为空
		if (oldFileName == null || oldFileName.equals("")) {
			return false;
		}
		// 新文件名不能为空
		if (newFileName == null || newFileName.equals("")) {
			return false;
		}
		// 名称相同
		if (oldFileName.equals(newFileName)) {
			return false;
		}
		if (!filePath.endsWith(File.separator)) {
			filePath = filePath + File.separator;
		}
		File oldFile = new File(filePath + oldFileName);
		// 更名的文件不存在
		if (!oldFile.exists()) {
			//如果目录不存在则创建，如果是文件，则返回false
			if (oldFile.isDirectory()) {
				oldFile.mkdirs();
			} else {
				return false;
			}
		}
		File newFile = new File(filePath + newFileName);
		// 已经有同名的文件或目录
		if (newFile.exists()) {
			return false;
		}
		return oldFile.renameTo(newFile);
	}
}
